<template>
    <el-row>
        <el-col :span="16">
            <el-cascader v-if="visible"
                filterable
                clearable
                :filter-method="filterMethod"
                ref="placeRef"
                :style="'width:' + width"
                v-model="value"
                separator="-"
                :disabled="disabled"
                :props="mapProps"
                :options="mapOptions"
                @change="onMapChange"
            ></el-cascader>
        </el-col>
        <el-col :span="8">
            <el-input v-model="detail" :disabled="disabled"></el-input>
        </el-col>
    </el-row>
</template>
<script>
import service from '@/utils/request'
// eslint-disable-next-line no-unused-vars
const { httpPostForm, httpPost, httpGet } = service
export default {
    name: 'SelectAddr',
    model: {
        prop: 'addr',
        event: 'changeAddr'
    },
    props: {
        showCountry: {
            type: Boolean,
            default: false
        },
        width: {
            type: String,
            default: '98%'
        },
        disabled: {
            type: Boolean,
            default: false
        },
        addr: {
            type: String,
            default: JSON.stringify({
                code: ['100000'],
                address: '',
                detail: ''
            })
        },
        lazy: {
            type: Boolean,
            default: false
        },
        isSelectOne: { // 只选省
            type: Boolean,
            default: false
        }
    },
    computed: {
        value: {
            get () {
                let result
                try {
                    result = JSON.parse(this.addr).code
                } catch (error) {
                    result = []
                }
                return result
            },
            set (val) {
                let addr
                try {
                    if (this.addr) {
                        addr = JSON.parse(this.addr)
                        // 如果是默认值，则设置详细地址为传入
                        if (addr.address === '') {
                            addr = JSON.parse(this.initData)
                        }
                    } else {
                        addr = JSON.parse(this.initData)
                    }
                } catch (error) {
                    addr = {
                        detail: ''
                    }
                }
                if (!val) {
                    return JSON.stringify({
                        code: ['100000'],
                        address: '',
                        detail: ''
                    })
                }
                let labelArr = []
                const mapObj = this.mapData
                val.forEach((item, index, arr) => {
                    let findObj
                    let obj
                    if (index === 0) {
                        obj = mapObj[this.rootId]
                    } else if (index < arr.length) {
                        obj = mapObj[arr[index - 1]]
                    }
                    findObj = obj.find(subItem => item === subItem.districtCode)
                    labelArr.push(findObj.districtName)
                })
                // this.$emit('getLabel', labelArr)
                const result = {
                    code: val,
                    address: labelArr,
                    detail: addr.detail
                }
                this.$emit('changeAddr', JSON.stringify(result))
            }
        },
        detail: {
            get () {
                let detailResult
                try {
                    detailResult = JSON.parse(this.addr).detail
                } catch (error) {
                    detailResult = ''
                }
                return detailResult
            },
            set (val) {
                let addr
                try {
                    addr = JSON.parse(this.addr)
                    addr.detail = val
                } catch (error) {
                    addr = {
                        code: ['100000'],
                        address: '',
                        detail: val
                    }
                }
                this.initData = JSON.stringify(addr)
                this.$emit('changeAddr', this.initData)
            }
        }
    },
    watch: {
        addr (val, oldVal) {
            let result
            try {
                result = JSON.parse(val)
            } catch (error) {
                result = {}
            }
            if (result.addr && result.addr === '') {
                this.initData = oldVal
            }
            if (val && this.firstLoad && !this.mapOptions.length && oldVal) {
                const { node, resolve } = this.treeMapData['-1']
                this.loadMap(node, resolve)
            }
        }
    },
    data () {
        return {
            firstLoad: true,
            visible: true,
            initData: '',
            mapProps: {
                value: 'districtCode',
                label: 'districtName',
                leaf: 'isLeaf',
                checkStrictly: true
            },
            mapOptions: [],
            mapData: {},
            treeMapData: {},
            rootId: '',
        }
    },
    created () {
        if (this.lazy) {
            this.mapProps.lazy = this.lazy
            this.mapProps.lazyLoad = this.loadMap
        }
    },
    mounted () {
        this.initData = this.addr
    },
    methods: {
        onMapChange (val) {
            console.log(val)
        },
        loadMap (node, resolve) {
            if (!node.root && !node.hasChildren) {
                resolve([])
                return
            }
            const key = node.value || '-1'
            if (!this.treeMapData[key]) {
                this.treeMapData[key] = { node, resolve }
            }
            let addr
            try {
                addr = JSON.parse(this.addr).code
            } catch (error) {
                addr = []
            }
            const mapData = this.mapData
            let distCode = node.value
            if (this.isRootNode(node)) {
                if (this.showCountry) {
                    distCode = ''
                    this.rootId = '-1'
                } else {
                    distCode = '100000'
                    this.rootId = distCode
                }

                node.value = this.rootId
            }
            // 如果已有，则直接返回
            if (mapData[node.value]) {
                resolve(mapData[node.value])
                return
            }
            // 获取第1级
            httpGet({
                url: '/config/dist/getDist',
                params: {
                    distCode
                }
            }).then(async res => {
                const resData = res.reverse()
                mapData[node.value] = resData
                if (this.isRootNode(node) && this.firstLoad && addr.length > 0) {
                    // 获取回显数据选项
                    const curNode = resData.find(item => item.districtCode === addr[0])
                    const txtArr = [curNode.districtName]
                    this.getMapOptions({ i: 1, curNode, addr, txtArr, mapData })
                }
                // 如果父页面未赋初值，则直接设为中国
                if (this.addr === '') {
                    this.$set(this, 'value', ['100000'])
                }
                resolve(resData)
            })
        },
        // 获取列表，作为回显
        getMapOptions ({ i, curNode, addr, txtArr, mapData }) {
            let distCode
            let resData
            // 取得上一级的子级列表作为children
            distCode = addr[i - 1]
            // 找到则不用再请求
            if (mapData[distCode]) {
                resData = mapData[distCode]
                this.setOption({ i, curNode, addr, txtArr, mapData, resData })
            } else {
                // 没有获取过则发送请求
                httpGet({
                    url: '/config/dist/getDist',
                    params: {
                        distCode
                    }
                }).then(resData => {
                    this.setOption({ i, curNode, addr, txtArr, mapData, resData })
                })
            }
        },
        setOption ({ i, curNode, addr, txtArr, mapData, resData }) {
            // 设置children
            if (curNode) {
                curNode.children = resData
                mapData[curNode.districtCode] = resData
            }
            // 找到当前选中节点
            curNode = resData.find(item => item.districtCode === addr[i])
            if (!curNode) {
                this.refreshComp(addr)
                return
            }
            txtArr.push(curNode.districtName)
            i++
            if (i < addr.length) {
                this.getMapOptions({ i, curNode, addr, txtArr, mapData })
            } else {
                this.refreshComp(addr)
            }
        },
        // 重新刷新组件，回显
        refreshComp (addr) {
            this.visible = false
            this.$nextTick(() => {
                this.$set(this, 'value', addr)
                this.visible = true
                this.firstLoad = false
            })
        },
        // 判断是否根节点
        isRootNode (node) {
            return node.level === 0
        },
        filterMethod (node, keyword) {
            return node.label.includes(keyword)
        }
    }
}
</script>
<style rel="stylesheet/scss" lang="scss">
.el-cascader-menu__wrap{
    height: 400px;
}
.el-scrollbar__bar.is-vertical{
    width: 12px;
}
.el-cascader-node__postfix{
    right: 20px;
}
</style>